Media Session API'si ile medya bildirimlerini ve oynatma kontrollerini özelleştirme

Donanım medya anahtarlarıyla entegrasyon, medya bildirimlerini özelleştirme ve daha fazlası.

François Beaufort
François Beaufort

Kullanıcıların tarayıcılarında o anda nelerin oynatıldığını bilmelerini ve oynatılan içeriği, içeriği başlatan sayfaya dönmeden kontrol etmelerini sağlamak için Media Session API kullanıma sunulmuştur. Web geliştiricilerinin, özel medya bildirimlerindeki meta veriler, oynatma, duraklatma, arama, parça değiştirme gibi medya etkinlikleri ve mikrofonu kapatma/açma, kamerayı açma/kapatma ve telefonu kapatma gibi video konferans etkinlikleri aracılığıyla bu deneyimi özelleştirmesine olanak tanır. Bu özelleştirmeler, masaüstü medya merkezleri, mobil cihazlardaki medya bildirimleri ve hatta giyilebilir cihazlar gibi çeşitli bağlamlarda kullanılabilir. Bu özelleştirmeleri bu makalede açıklayacağım.

Medya oturumu bağlamlarının ekran görüntüleri.
Masaüstünde medya merkezi, mobil cihazda medya bildirimi ve giyilebilir cihaz.

Media Session API hakkında

Media Session API, çeşitli avantajlar ve özellikler sunar:

  • Donanım medya anahtarları desteklenir.
  • Medya bildirimleri mobil cihazlarda, masaüstü bilgisayarlarda ve eşlenmiş giyilebilir cihazlarda özelleştirilebilir.
  • Medya merkezi masaüstünde kullanılabilir.
  • Kilit ekranı medya kontrolleri ChromeOS ve mobil cihazlarda kullanılabilir.
  • Pencere içinde pencere kontrolleri, ses oynatma, görüntülü toplantı ve slayt sunma için kullanılabilir.
  • Mobil cihazlarda Asistan entegrasyonu kullanılabilir.

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 82.
  • Safari: 15.

Source

Bu noktalardan bazılarını birkaç örnekle açıklayacağız.

1. Örnek: Kullanıcılar klavyelerindeki "sonraki parça" medya tuşuna basarsa web geliştiricileri, tarayıcı ön planda veya arka planda olsun bu kullanıcı işlemini işleyebilir.

2. örnek: Kullanıcılar, cihaz ekranları kilitliyken web'de podcast dinlerken kilit ekranındaki medya kontrollerinden "geri sar" simgesine basabilir. Böylece web geliştiricileri, oynatma süresini birkaç saniye geriye çekebilir.

3. Örnek: Kullanıcıların ses çalan sekmeleri varsa web geliştiricilerin durumlarını temizleyebilmesi için masaüstündeki medya merkezinden oynatmayı kolayca durdurabilirler.

4. Örnek: Kullanıcılar görüntülü görüşme yapıyorsa web sitesinin mikrofon verilerini almasını durdurmak için Pencere İçinde Pencere penceresindeki "Mikrofonu aç/kapat" denetimine basabilirler.

Tüm bu işlemler iki farklı arayüz üzerinden yapılır: MediaSession arayüzü ve MediaMetadata arayüzü. İlki, oynatılan içeriği kontrol etmelerini sağlar. İkincisi, MediaSession'ye nelerin kontrol edilmesi gerektiğini nasıl söylediğinizdir.

Aşağıdaki resimde, bu arayüzlerin belirli medya kontrolleri (bu örnekte mobil cihazlardaki medya bildirimleri) ile nasıl ilişkili olduğu gösterilmektedir.

Medya oturumu arayüzleri görseli.
Mobil cihazlarda medya bildiriminin anatomisi.

Kullanıcılara nelerin çalındığını bildirin

Bir web sitesinde ses veya video oynatıldığında kullanıcılar mobil cihazlardaki bildirim tepsisine ya da masaüstündeki medya merkezine otomatik olarak medya bildirimleri alır. Tarayıcı, belgenin başlığını ve bulabileceği en büyük simge resmini kullanarak uygun bilgileri göstermek için elinden geleni yapar. Media Session API ile medya bildirimini, aşağıdaki gibi başlık, sanatçı adı, albüm adı ve poster gibi daha zengin medya meta verileriyle özelleştirebilirsiniz.

Chrome, medya bildirimlerini yalnızca medya süresi en az 5 saniye olduğunda göstermek için "tam" ses odağını ister. Bu sayede, zil sesleri gibi arızi sesler bildirim olarak gösterilmez.

// After media (video or audio) starts playing
await document.querySelector("video").play();

if ("mediaSession" in navigator) {
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    artist: 'Rick Astley',
    album: 'Whenever You Need Somebody',
    artwork: [
      { src: 'https://via.placeholder.com/96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/192', sizes: '192x192', type: 'image/png' },
      { src: 'https://via.placeholder.com/256', sizes: '256x256', type: 'image/png' },
      { src: 'https://via.placeholder.com/384', sizes: '384x384', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  });

  // TODO: Update playback state.
}

Oynatma sona erdiğinde bildirim otomatik olarak kaybolacağı için medya oturumunu "bırakmanıza" gerek yoktur. Ancak bir sonraki oynatma işlemi başladığında navigator.mediaSession.metadata değerinin kullanılacağını unutmayın. Bu nedenle, medya oynatma kaynağı değiştiğinde medya bildirimindeki bilgilerin alakalı olduğundan emin olmak için bu kaynağı güncellemeniz önemlidir.

Medya meta verileriyle ilgili dikkat edilmesi gereken birkaç nokta vardır.

  • Bildirim posteri dizisi, blob URL'lerini ve veri URL'lerini destekler.
  • Poster tanımlanmamışsa ve istenilen boyutta bir simge resmi (<link rel=icon> kullanılarak belirtilmiş) varsa medya bildirimleri bu resmi kullanır.
  • Android için Chrome'da bildirim posteri hedef boyutu 512x512'tür. Düşük özellikli cihazlarda bu değer 256x256'tür.
  • Medya HTML öğesinin title özelliği, "Şu anda çalan" macOS widget'ında kullanılır.
  • Medya kaynağı yerleştirilmişse (örneğin, bir iframe'e) Media Session API bilgileri, yerleştirilmiş bağlamda ayarlanmalıdır. Aşağıdaki snippet'i inceleyin.
<iframe id="iframe">
  <video>...</video>
</iframe>
<script>
  iframe.contentWindow.navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Never Gonna Give You Up',
    ...
  });
</script>

Medya meta verilerine bölüm bilgileri (ör. bölümün başlığı, zaman damgası ve ekran görüntüsü) de ekleyebilirsiniz. Bu sayede kullanıcılar medya içeriğinde gezinebilir.

navigator.mediaSession.metadata = new MediaMetadata({
  // title, artist, album, artwork, ...
  chapterInfo: [{
    title: 'Chapter 1',
    startTime: 0,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }, {
    title: 'Chapter 2',
    startTime: 42,
    artwork: [
      { src: 'https://via.placeholder.com/128', sizes: '128x128', type: 'image/png' },
      { src: 'https://via.placeholder.com/512', sizes: '512x512', type: 'image/png' },
    ]
  }]
});
ChromeOS medya bildirimlerinde gösterilen bölüm bilgileri.
ChromeOS'te bölümlerin yer aldığı medya bildirimi.

Kullanıcıların oynatılan içeriği kontrol etmesine izin verme

Medya oturumu işlemi, kullanıcılar mevcut medya oynatmasıyla etkileşime geçtiğinde web sitesinin kullanıcılar için işleyebileceği bir işlemdir (ör. "oynat" veya "duraklat"). İşlemler, etkinliklere benzer ve etkinliklerle hemen hemen aynı şekilde çalışır. Etkinlikler gibi işlemler de uygun bir nesneye (bu örnekte MediaSession örneği) işleyiciler ayarlanarak uygulanır. Bazı işlemler, kullanıcılar bir kulaklıkta, başka bir uzaktan cihazda veya klavyede düğmelere bastığında ya da medya bildirimiyle etkileşimde bulunduğunda tetiklenir.

Windows 10&#39;daki bir medya bildiriminin ekran görüntüsü.
Windows 10'da özelleştirilmiş medya bildirimi.

Bazı medya oturumu işlemleri desteklenmediğinden, bunları ayarlarken try…catch bloğu kullanmanız önerilir.

const actionHandlers = [
  ['play',          () => { /* ... */ }],
  ['pause',         () => { /* ... */ }],
  ['previoustrack', () => { /* ... */ }],
  ['nexttrack',     () => { /* ... */ }],
  ['stop',          () => { /* ... */ }],
  ['seekbackward',  (details) => { /* ... */ }],
  ['seekforward',   (details) => { /* ... */ }],
  ['seekto',        (details) => { /* ... */ }],
  /* Video conferencing actions */
  ['togglemicrophone', () => { /* ... */ }],
  ['togglecamera',     () => { /* ... */ }],
  ['hangup',           () => { /* ... */ }],
  /* Presenting slides actions */
  ['previousslide', () => { /* ... */ }],
  ['nextslide',     () => { /* ... */ }],
];

for (const [action, handler] of actionHandlers) {
  try {
    navigator.mediaSession.setActionHandler(action, handler);
  } catch (error) {
    console.log(`The media session action "${action}" is not supported yet.`);
  }
}

Bir medya oturumu işlem işleyicisinin ayarını kaldırmak, null olarak ayarlamak kadar kolaydır.

try {
  // Unset the "nexttrack" action handler at the end of a playlist.
  navigator.mediaSession.setActionHandler('nexttrack', null);
} catch (error) {
  console.log(`The media session action "nexttrack" is not supported yet.`);
}

Medya oturumu işlem işleyicileri, ayarlandıktan sonra medya oynatmaları boyunca devam eder. Bu, etkinlik dinleyici kalıbına benzer. Bununla birlikte, bir etkinliğin işlenmesi, tarayıcının varsayılan davranışı durdurması anlamına gelir ve bunu web sitesinin medya işlemini desteklediğinin bir sinyali olarak kullanır. Bu nedenle, uygun işlem işleyici ayarlanmazsa medya işlemi kontrolleri gösterilmez.

macOS Big Sur&#39;daki Şu Anda Çalan widget&#39;ının ekran görüntüsü.
macOS Big Sur'daki Oynatılanlar widget'ı.

Oynat / duraklat

"play" işlemi, kullanıcının medya oynatmayı devam ettirmek istediğini, "pause" işlemi ise geçici olarak durdurmak istediğini belirtir.

"Oynat/duraklat" simgesi, medya bildirimlerinde her zaman gösterilir ve ilgili medya etkinlikleri tarayıcı tarafından otomatik olarak yönetilir. Varsayılan davranışlarını geçersiz kılmak için "oynatma" ve "duraklatma" medya işlemlerini aşağıda gösterildiği gibi kullanın.

Tarayıcı, örneğin bir web sitesini aradığında veya yüklerken medya oynatmadığını düşünebilir. Bu durumda, web sitesi kullanıcı arayüzünün medya bildirimi kontrolleriyle senkronize kalmasını sağlamak için navigator.mediaSession.playbackState değerini "playing" veya "paused" olarak ayarlayarak bu davranışı geçersiz kılın.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('play', async () => {
  // Resume playback
  await video.play();
});

navigator.mediaSession.setActionHandler('pause', () => {
  // Pause active playback
  video.pause();
});

video.addEventListener('play', () => {
  navigator.mediaSession.playbackState = 'playing';
});

video.addEventListener('pause', () => {
  navigator.mediaSession.playbackState = 'paused';
});

Önceki parça

"previoustrack" işlemi, kullanıcının mevcut medya oynatmayı baştan başlatmak istediğini (medya oynatmanın başlangıç kavramı varsa) veya oynatma listesinde önceki öğeye geçmek istediğini (medya oynatmanın oynatma listesi kavramı varsa) gösterir.

navigator.mediaSession.setActionHandler('previoustrack', () => {
  // Play previous track.
});

Sonraki parça

"nexttrack" işlemi, medya oynatmanın oynatma listesi kavramına sahip olması durumunda kullanıcının medya oynatmayı oynatma listesindeki bir sonraki öğeye taşımak istediğini belirtir.

navigator.mediaSession.setActionHandler('nexttrack', () => {
  // Play next track.
});

Durdur

"stop" işlemi, kullanıcının medya oynatmayı durdurmak ve uygunsa durumu temizlemek istediğini gösterir.

navigator.mediaSession.setActionHandler('stop', () => {
  // Stop playback and clear state if appropriate.
});

Geri / ileri sar

"seekbackward" işlemi, kullanıcının medya oynatma süresini kısa bir süre geriye taşımak istediğini, "seekforward" işlemi ise medya oynatma süresini kısa bir süre ileri taşımak istediğini gösterir. Her iki durumda da kısa süre birkaç saniye anlamına gelir.

İşlem işleyicisinde sağlanan seekOffset değeri, medya oynatma süresinin saniye cinsinden ne kadar kaydırılmasını istediğinizi belirtir. Bu değer sağlanmazsa (örneğin, undefined) makul bir süre (örneğin, 10-30 saniye) kullanmanız gerekir.

const video = document.querySelector('video');
const defaultSkipTime = 10; /* Time to skip in seconds by default */

navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.max(video.currentTime - skipTime, 0);
  // TODO: Update playback state.
});

navigator.mediaSession.setActionHandler('seekforward', (details) => {
  const skipTime = details.seekOffset || defaultSkipTime;
  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
  // TODO: Update playback state.
});

Belirli bir zamana gitme

"seekto" işlemi, kullanıcının medya oynatma süresini belirli bir zamana taşımak istediğini gösterir.

İşlem işleyicisinde sağlanan seekTime değeri, medya oynatma süresinin taşınacağı saniye cinsinden süredir.

İşlem, bir dizinin parçası olarak birden çok kez çağrılıyorsa ve bu, söz konusu dizinin son çağrısı değilse işlem işleyicisinde sağlanan fastSeek boole değeri doğru olur.

const video = document.querySelector('video');

navigator.mediaSession.setActionHandler('seekto', (details) => {
  if (details.fastSeek && 'fastSeek' in video) {
    // Only use fast seek if supported.
    video.fastSeek(details.seekTime);
    return;
  }
  video.currentTime = details.seekTime;
  // TODO: Update playback state.
});

Oynatma konumunu ayarlama

Bir bildirimde medya oynatma konumunu doğru şekilde göstermek, aşağıda gösterildiği gibi konum durumunu uygun bir zamanda ayarlamak kadar kolaydır. Konum durumu, medya oynatma hızı, süresi ve geçerli zamanın bir birleşimidir.

ChromeOS&#39;teki kilit ekranı medya denetimlerinin ekran görüntüsü.
ChromeOS'te kilit ekranı medya kontrolleri.

Süre belirtilmeli ve pozitif olmalıdır. Konum pozitif olmalı ve süreden az olmalıdır. Oynatma hızı 0'dan büyük olmalıdır.

const video = document.querySelector('video');

function updatePositionState() {
  if ('setPositionState' in navigator.mediaSession) {
    navigator.mediaSession.setPositionState({
      duration: video.duration,
      playbackRate: video.playbackRate,
      position: video.currentTime,
    });
  }
}

// When video starts playing, update duration.
await video.play();
updatePositionState();

// When user wants to seek backward, update position.
navigator.mediaSession.setActionHandler('seekbackward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek forward, update position.
navigator.mediaSession.setActionHandler('seekforward', (details) => {
  /* ... */
  updatePositionState();
});

// When user wants to seek to a specific time, update position.
navigator.mediaSession.setActionHandler('seekto', (details) => {
  /* ... */
  updatePositionState();
});

// When video playback rate changes, update position state.
video.addEventListener('ratechange', (event) => {
  updatePositionState();
});

Konum durumunu sıfırlamak, null olarak ayarlamak kadar kolaydır.

// Reset position state when media is reset.
navigator.mediaSession.setPositionState(null);

Video konferans işlemleri

Kullanıcı görüntülü görüşmesini Pencere İçinde Pencere penceresine yerleştirdiğinde tarayıcıda mikrofon, kamera ve görüşmeyi sonlandırma kontrolleri gösterilebilir. Kullanıcı bu düğmeleri tıkladığında web sitesi, aşağıdaki video konferansı işlemleriyle bunları işler. Örnek için Video Konferans örneğine bakın.

Pencere içinde pencere penceresindeki video konferans denetimlerinin ekran görüntüsü.
Pencere içinde pencere penceresindeki video konferans kontrolleri.

Mikrofonu aç/kapat

"togglemicrophone" işlemi, kullanıcının mikrofonun sesini kapatmak veya açmak istediğini gösterir. setMicrophoneActive(isActive) yöntemi, web sitesinin şu anda mikrofonu etkin olarak görüp görmediğini tarayıcıya bildirir.

let isMicrophoneActive = false;

navigator.mediaSession.setActionHandler('togglemicrophone', () => {
  if (isMicrophoneActive) {
    // Mute the microphone.
  } else {
    // Unmute the microphone.
  }
  isMicrophoneActive = !isMicrophoneActive;
  navigator.mediaSession.setMicrophoneActive(isMicrophoneActive);
});

Kamerayı değiştir

"togglecamera" işlemi, kullanıcının etkin kamerayı açmak veya kapatmak istediğini gösterir. setCameraActive(isActive) yöntemi, tarayıcının web sitesini etkin olarak görüp görmediğini belirtir.

let isCameraActive = false;

navigator.mediaSession.setActionHandler('togglecamera', () => {
  if (isCameraActive) {
    // Disable the camera.
  } else {
    // Enable the camera.
  }
  isCameraActive = !isCameraActive;
  navigator.mediaSession.setCameraActive(isCameraActive);
});

Kapatın.

"hangup" işlemi, kullanıcının bir aramayı sonlandırmak istediğini gösterir.

navigator.mediaSession.setActionHandler('hangup', () => {
  // End the call.
});

Slayt gösterme işlemleri

Kullanıcı, slayt sunumunu bir Pencere İçinde Pencere penceresine yerleştirdiğinde tarayıcı, slaytlar arasında gezinmeyle ilgili kontrolleri gösterebilir. Kullanıcı bu bağlantıları tıkladığında web sitesi, Media Session API üzerinden bu bağlantıları işler. Örnek için Slaytlar sunma örneğine bakın.

Önceki slayt

"previousslide" işlemi, kullanıcının slaytları sunarken önceki slayta geri dönmek istediğini gösterir.

navigator.mediaSession.setActionHandler('previousslide', () => {
  // Show previous slide.
});

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: not supported.
  • Safari: not supported.

Sonraki slayt

"nextslide" işlemi, kullanıcının slaytları sunarken bir sonraki slayta gitmek istediğini gösterir.

navigator.mediaSession.setActionHandler('nextslide', () => {
  // Show next slide.
});

Browser Support

  • Chrome: 111.
  • Edge: 111.
  • Firefox: not supported.
  • Safari: not supported.

Örnekler

Blender Foundation ve Jan Morgenstern'ın çalışmalarının yer aldığı bazı medya oturumu örneklerine göz atın.

Media Session API'yi gösteren bir ekran kaydı.

Kaynaklar